/*
   Copyright (c) 2019 Shanghai Xuanzi Technology Co. Ltd https://xuanzi.ltd
   XZMindMap is licensed under the Mulan PSL v1.
   You can use this software according to the terms and conditions of the Mulan PSL v1.
   You may obtain a copy of Mulan PSL v1 at:
      http://license.coscl.org.cn/MulanPSL
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
   PURPOSE.
   See the Mulan PSL v1 for more details.

*/

package xuanzi.openmind.nodes;

import java.util.ArrayList;
import java.util.List;import org.junit.platform.launcher.listeners.SummaryGeneratingListener;

import xuanzi.commons.graphics.Canvas;
import xuanzi.commons.graphics.Paint;
import xuanzi.commons.graphics.PointF;
import xuanzi.openmind.layout.Box;
import xuanzi.openmind.renders.RenderBuffer;
import xuanzi.openmind.themes.Theme;

public class Sheet {

	public static  boolean debug = false;

	public Sheet() { 
		viewBox.union(800,800);
		viewBox.offsetTo(-viewBox.width()/2, -viewBox.height()/2);
		theme = new Theme();
	}
	
	String name;
	
	int sheetIndex;
	
	String id;
	
	Node root;
	
	List<Node> freenNodes;
	
	Background background;
	
	public Box getViewBox() {
		return viewBox;
	}
	
	Box viewBox = new Box(800,800);
	
	List<Summary> summaryList ;
	
	List<Group> groupList;
	
	List<Contact> contactList;
	 
	float scale = 1;
	
	public void scroll(float x,float y) {
		dirty = true; 
		viewBox.offset(x, y);
		root.renderBuffer.checkVisable(root,viewBox);
	}
	
	
	PointF testPoint;
	
	public Node testPoint(PointF point) {
		testPoint = point;
		return root.testPoint(point);
	}
	
	float centerX,centerY;
 
	
	public void scrollTo(float x,float y) {
		centerX = x;
		centerY = y;
		dirty = true;
		
		viewBox.offsetTo(x-viewBox.width()/2, y-viewBox.height()/2); 
		root.renderBuffer.checkVisable(root,viewBox);
		 
	}
	
	public void scale(float scale) {
		this.scale = scale;
		dirty = true;
		willDraw();
	}
	
	public void willDraw() {
	 
	}
	
	public Node testPicturePoint(PointF point) {
		// TODO Auto-generated method stub
		//PointF xx = root.getScene().getPictureCenter();
		PointF pp = getPointFromPicture(point);
		return testPoint(pp);
	}
	
	public PointF getPointFromPicture(PointF point) {
		point.x = point.x+viewBox.left;
		point.y = point.y+viewBox.top;
		return point;
	}

	public void layoutChange() { 
		layoutChange(true);
	}
	public void layoutChange(boolean checkVisable) { 
		root.getScene().setupNode(root,this);
		if(checkVisable)
			root.renderBuffer.checkVisable(root,viewBox);
		if(freenNodes!=null) {
			for(Node item : freenNodes) {
				item.requestLayout(); 
			}
		}
		dirty = true;
		if(groupList!=null) {
			for(Group group:groupList) {
				group.onLayout(viewBox);
			}
		}
		if(contactList!=null) {
			for(Contact group:contactList) {
				group.onLayout(viewBox);
			}
		}
		if(summaryList!=null) {
			for(Summary group:summaryList) {
				group.onLayout(viewBox);
			}
		}
		willDraw(); 
	}
	
	public void draw(Canvas canvas) {
		canvas.save();  
		//canvas.drawText( viewBox.left+","+ viewBox.top, 
		//		 viewBox.left,  viewBox.top, RenderBuffer.paint);
		canvas.translate(-viewBox.left,-viewBox.top);
		if(debug)
			
			canvas.save();
		//	canvas.translate(-root.getNodeBound().centerX(), -root.getNodeBound().centerY()); 
			if(background!=null) {
				background.setViewBox(viewBox);
				background.draw(canvas);
			}else {
				RenderBuffer.paint.fill(0xFFFFFFFF);
				canvas.drawRect( viewBox, RenderBuffer.paint); 
			}
				drawAll(canvas); 
		//	canvas.restore(); 
		canvas.restore(); 
	}
	
	public void drawAll(Canvas canvas) { 
		
	 
		root.draw(canvas);
		if(freenNodes!=null) {
			for(Node node:freenNodes) {
				canvas.save();
				canvas.translate(node.getCenterX(), node.getCenterY());
				node.draw(canvas);
				canvas.restore();
			}
		}
		
		if(groupList!=null) {
			for(Group group:groupList) {
				group.draw(canvas);
			}
		}
		if(contactList!=null) {
			for(Contact group:contactList) {
				group.draw(canvas);
			}
		}
		if(summaryList!=null) {
			for(Summary group:summaryList) {
				group.draw(canvas);
			}
		}
		if(testPoint!=null) {
			canvas.drawLine(testPoint.x-10, testPoint.y-10, testPoint.x+10,testPoint.y-10, RenderBuffer.paint);

			canvas.drawLine(testPoint.x+10, testPoint.y-10, testPoint.x+10,testPoint.y+10, RenderBuffer.paint);
			canvas.drawLine(testPoint.x+10, testPoint.y+10, testPoint.x-10,testPoint.y+10, RenderBuffer.paint);
			canvas.drawLine(testPoint.x-10, testPoint.y+10, testPoint.x-10,testPoint.y-10, RenderBuffer.paint);
		}
	}
	
	public void drawPicture(Canvas canvas) { 
		canvas.save();
		canvas.translate(-root.renderBuffer.scene.box().left, -root.renderBuffer.scene.box().top);
		drawAll(canvas);
		canvas.restore();
	}

	Paint paint = new Paint();
	
	
	/**
	 * 是否需要重新绘制
	 */
	boolean dirty = true;
	
	public Background getBackground() {
		return background;
	}
	
	public void setBackground(Background background) {
		this.background = background;
	}

	public Node getRoot() {
		return root;
	}

	public void setRoot(Node root) {
		this.root = root;
	}

	public List<Node> getFreenNodes() {
		return freenNodes;
	}

	public void setFreenNodes(List<Node> freenNodes) {
		this.freenNodes = freenNodes;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getSheetIndex() {
		return sheetIndex;
	}

	public void setSheetIndex(int sheetIndex) {
		this.sheetIndex = sheetIndex;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void addContact(Contact c) {
		if(contactList==null)
			contactList = new ArrayList<Contact>();
		
		contactList.add(c);
		
	}

	public void addSummary(Summary sum) {
		if(summaryList==null)
			summaryList = new ArrayList<>();
		summaryList.add(sum);	
	}

	public void addGroup(Group sum) {
		if(groupList==null)
			groupList = new ArrayList<Group>();
		
		groupList.add(sum);
	}
	
	Theme theme;

	public void setTheme(Theme theme) {
		// TODO Auto-generated method stub
		this.theme = theme;
	}

	public Theme getTheme() {
		return theme;
	}


	
}
